package evan.zhang.flags;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.google.android.maps.GeoPoint;

import android.util.Log;
import android.widget.Toast;

public class FlagsGeocoder {

	private final static String tag = "FlagsOnMap::FlagsGeocoder";
	private final static String urlBase = "http://maps.google.com/maps/api/geocode/json?region=cn&sensor=false";
	private String urlWithLanguage;
	private String status = "";
	private String types = "";
	private String formattedAddress = "";
	private String countryName = "";
	//private boolean hasLocation = false;
	private GeoPoint location = new GeoPoint(0,0);
	//private boolean hasViewport = false;
	private int[] vSpan = new int[2];
	private boolean hasBounds = false;
	private int[] bSpan = new int[2];

	public String getStatus() {
		return this.status;
	}
	public String getTypes() {
		return this.types;
	}
	public String getFormattedAddress() {
		return this.formattedAddress;
	}
	public String getCountryName() {
		return this.countryName;
	}
	//public boolean hasLocation() {
	//	return this.hasLocation;
	//}
	public GeoPoint getLocation() {
		return this.location;
	}
	//public boolean hasViewport() {
	//	return this.hasViewport;
	//}
	public int[] getVSpan() {
		return this.vSpan;
	}
	public boolean hasBounds() {
		return this.hasBounds;
	}
	public int[] getBSpan() {
		return this.bSpan;
	}
	public FlagsGeocoder(String language) {
		this.urlWithLanguage = FlagsGeocoder.urlBase+"&language="+language;
	}
	
	public boolean isCountry() {
		if (this.types.equals("country")) {
			return true;
		} else {
			return false;
		}
	}
	public boolean getResponseData(String inputAddress) {
		URL url; 
    	String responseString;
    	String urlString;
		try {
			//urlString = urlWithLanguage+"&address="+inputAddress.replaceAll(" ", "%20");
			urlString = urlWithLanguage+"&address="+URLEncoder.encode(inputAddress);
			Log.d(tag, "urlString = "+urlString);
			url = new URL(urlString);
			BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
			String temp;
			StringBuilder stringBuilder = new StringBuilder();
			while ((temp = in.readLine()) != null) {
                stringBuilder.append(temp);
            }
            in.close();
            responseString = stringBuilder.toString();
	        Log.d(tag, responseString);
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			//Toast.makeText(context, "Network error, try it later!", Toast.LENGTH_LONG).show();
			return false;
		}
		
		
		
		JSONObject responseObject;
		JSONArray resultArray;
		try {
			responseObject = (JSONObject) new JSONTokener(responseString).nextValue(); 
			//status
			this.status = responseObject.getString("status");
			if (this.status.equals("OK")) {		
				resultArray = responseObject.getJSONArray("results");
				JSONObject firstResult = (JSONObject) resultArray.get(0);
				//types
				this.types = (String)firstResult.getJSONArray("types").get(0);
				//formattedAddress
				this.formattedAddress = firstResult.getString("formatted_address");
				JSONArray addressCom = firstResult.getJSONArray("address_components");
				for (int i=0;i<addressCom.length(); i++) {
					JSONObject temp = (JSONObject)addressCom.get(i);
					if (((String)temp.getJSONArray("types").get(0)).equals("country")) {
						//countryName
						this.countryName = (String)temp.getString("long_name");
					}
				}
				JSONObject geometry = firstResult.getJSONObject("geometry");
			    double lat = geometry.getJSONObject("location").getDouble("lat");
			    double lng = geometry.getJSONObject("location").getDouble("lng");
			    //location
			    this.location = new GeoPoint((int)(lat*1E6),(int)(lng*1E6));
			    JSONObject viewport = firstResult.getJSONObject("geometry").getJSONObject("viewport");
			    float swLat = Float.parseFloat(viewport.getJSONObject("southwest").getString("lat"));
				float swLng = Float.parseFloat(viewport.getJSONObject("southwest").getString("lng"));
				float neLat = Float.parseFloat(viewport.getJSONObject("northeast").getString("lat"));
				float neLng = Float.parseFloat(viewport.getJSONObject("northeast").getString("lng"));
				//vSpan
				this.vSpan[0] = (int)((neLat-swLat)*1E6);
				this.vSpan[1] = (int)((neLng-swLng)*1E6);
				
				
				if (firstResult.getJSONObject("geometry").has("bounds")) {
					//hasBounds
					this.hasBounds = true;
					JSONObject bounds = firstResult.getJSONObject("geometry").getJSONObject("bounds");
					swLat = Float.parseFloat(bounds.getJSONObject("southwest").getString("lat"));
					swLng = Float.parseFloat(bounds.getJSONObject("southwest").getString("lng"));
					neLat = Float.parseFloat(bounds.getJSONObject("northeast").getString("lat"));
					neLng = Float.parseFloat(bounds.getJSONObject("northeast").getString("lng"));
					//bSpan
					this.bSpan[0] = (int)((neLat-swLat)*1E6);
					this.bSpan[1] = (int)((neLng-swLng)*1E6);
				}
				return true;
			} else {
				//Toast.makeText(context, "Network error, try it later!", Toast.LENGTH_LONG).show();
				return false;
			}		
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		}
	}//end of function
}//end of class
